using System.Threading.Tasks;
using Abp.Application.Services;
using Abp.Aspects;
using Abp.AspNetCore.Configuration;
using Abp.AspNetCore.Mvc.Extensions;
using Abp.Dependency;
using Microsoft.AspNetCore.Mvc.Filters;

namespace Abp.AspNetCore.Mvc.Validation;

public class AbpValidationActionFilter : IAsyncActionFilter, ITransientDependency
{
    private readonly IIocResolver _iocResolver;
    private readonly IAbpAspNetCoreConfiguration _configuration;

    public AbpValidationActionFilter(IIocResolver iocResolver, IAbpAspNetCoreConfiguration configuration)
    {
        _iocResolver = iocResolver;
        _configuration = configuration;
    }

    public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
    {
        if (!_configuration.IsValidationEnabledForControllers || !context.ActionDescriptor.IsControllerAction())
        {
            await next();
            return;
        }

        using (AbpCrossCuttingConcerns.Applying(context.Controller, AbpCrossCuttingConcerns.Validation))
        {
            using (var validator = _iocResolver.ResolveAsDisposable<MvcActionInvocationValidator>())
            {
                validator.Object.Initialize(context);
                validator.Object.Validate();
            }

            await next();
        }
    }
}